import random
import re
import time
from playwright.sync_api import Playwright, sync_playwright, expect
import traceback
import  os
from public_xue import get_filename_part, sleep
import time
import random
from datetime import datetime, timedelta

def amazon_initial(page):
    try:
        # 导航到登录页面
        postcode = [
            '10001', '10002', '10003', '10004', '10005', '10006', '10007', '10009', '10010', '10011', 
            '10012', '10013', '10014', '10016', '10017', '10018', '10019', '10020', '10021', '10022', 
            '10023', '10024', '10025', '10028', '10036', '60007', '60018', '60601', '60602', '60603', 
            '60604', '60605', '60606', '60607', '60608', '90001', '90002', '90003', '90004', '90005', 
            '90006', '90007', '90008', '90009', '90010', '90012', '90013', '90014', '90015', '90017', 
            '90019', '90020', '90024', '90025', '90026', '90028', '90029', '90034', '90035', '90036', 
            '90038', '90045', '90046', '90048', '90210', '90265', '90272', '90401', '90402', '90403', 
            '90404', '90405', '94102', '94103', '94104', '94105', '94107', '94108', '94109', '94110', 
            '94111', '94112', '94114', '94115', '94116', '94117', '94118', '94121', '94122', '94123', 
            '94124', '94127', '94129', '94130', '94131', '19102', '19103', '19104', '19106', '19107', 
            '33101', '33139', '77001', '77002', '77003', '77004', '77005', '20001', '20002', '20003'
        ]
        postcode_choice = random.choice(postcode)
        # page.goto("https://www.amazon.com/")
        postcode_choice = random.choice(postcode)
        print(postcode_choice)
        sleep(random.randint(1, 2)*random.random())
        human_like_scroll(page, 2)
        while not  page.is_visible("#glow-ingress-block"):
            sleep(random.uniform(0.1,0.2))
        page.hover("#glow-ingress-block")
        page.click("#glow-ingress-block")
        sleep(random.uniform(0.3,0.6))
        if page.is_visible("#GLUXZipUpdateInput"):
            page.fill("#GLUXZipUpdateInput", postcode_choice)
        sleep(random.uniform(0.3,0.6))
        if page.is_visible("a[id='GLUXChangePostalCodeLink'][role='link']"):
            page.hover("a[id='GLUXChangePostalCodeLink'][role='link']")
            page.click("a[id='GLUXChangePostalCodeLink'][role='link']")
            sleep(random.uniform(0.3,0.6))
            if page.is_visible("#GLUXZipUpdateInput"):
                page.fill("#GLUXZipUpdateInput", postcode_choice)

        # page.get_by_label("设置", exact=True).click()
        sleep(random.uniform(0.3,0.6))
        # 点击apply
        if page.is_visible("#GLUXZipUpdate input[type='submit']"):
            page.hover("#GLUXZipUpdate input[type='submit']")
            page.click("#GLUXZipUpdate input[type='submit']")
            sleep(random.uniform(0.3,0.6))
        # 点击done
        sleep(random.uniform(0.3,0.6))
        if page.is_visible("button[name='glowDoneButton'][type='button']"):
            page.hover("button[name='glowDoneButton'][type='button']")
            page.click("button[name='glowDoneButton'][type='button']")
            sleep(random.uniform(0.3,0.6))
        # page.get_by_role("button", name="完成").click()
       
    
        return True
        
    except Exception as e:
        print(f"亚马逊初始化过程中发生错误: {str(e)}")
        traceback.print_exc()
        return False
def human_like_scroll(page, total_duration=10, random_pause=True):
    """
    模拟人类自然滚动页面的行为，使用Python实现
    
    Args:
        page: playwright页面对象
        total_duration: 整个滚动过程花费的总时间(秒)
        random_pause: 是否添加随机暂停，模拟阅读行为
    """

    
    # 获取页面高度
    total_height = page.evaluate("() => document.body.scrollHeight")
    viewport_height = page.evaluate("() => window.innerHeight")
    
    # 计算初始的30%位置
    initial_position = int(total_height * 0.3)
    
    # 初始化当前位置为0
    current_position = 0
    
    # 第一步：快速滚动到30%位置(大约用时1/4总时间)
    first_step_duration = total_duration / 4
    start_time = time.time()
    end_time = start_time + first_step_duration
    
    print(f"开始模拟人类滚动行为, 总高度:{total_height}px, 第一步目标:{initial_position}px")
    
    while time.time() < end_time and current_position < initial_position:
        elapsed = time.time() - start_time
        progress = min(elapsed / first_step_duration, 1.0)
        
        # 使用平滑的缓动函数
        if progress < 0.5:
            eased_progress = 2 * progress * progress
        else:
            eased_progress = 1 - pow(-2 * progress + 2, 2) / 2
        
        # 计算新位置
        new_position = int(eased_progress * initial_position)
        scroll_amount = new_position - current_position
        
        # 执行滚动
        if scroll_amount > 0:
            page.mouse.wheel(0, scroll_amount)
            current_position = new_position
            
        # 短暂等待
        time.sleep(0.05)
    
    print(f"完成第一步滚动, 当前位置:{current_position}px")
    
    # 第二步：缓慢滚动到底部
    second_step_duration = total_duration - first_step_duration
    start_time = time.time()
    end_time = start_time + second_step_duration
    
    while time.time() < end_time and current_position < total_height:
        # 计算经过的时间比例
        elapsed = time.time() - start_time
        progress = min(elapsed / second_step_duration, 1.0)
        
        # 使用平滑的缓动函数
        if progress < 0.5:
            eased_progress = 2 * progress * progress
        else:
            eased_progress = 1 - pow(-2 * progress + 2, 2) / 2
        
        # 添加随机波动，模拟人类不规则滚动
        random_factor = 1 + (random.random() * 0.04 - 0.02)
        target_position = initial_position + int((total_height - initial_position) * eased_progress * random_factor)
        
        # 确保不超过页面底部
        target_position = min(target_position, total_height)
        
        # 计算滚动量
        scroll_amount = target_position - current_position
        
        # 执行滚动
        if scroll_amount > 0:
            page.mouse.wheel(0, scroll_amount)
            current_position = target_position
        
        # 随机暂停模拟阅读
        if random_pause and random.random() < 0.15:
            pause_time = 0.2 + random.random() * 0.8  # 0.2到1秒的暂停
            time.sleep(pause_time)
        else:
            time.sleep(0.05)  # 短暂等待
    
    # 确保滚动到底部
    if current_position < total_height:
        page.mouse.wheel(0, total_height - current_position)
        
    print(f"完成模拟人类滚动, 最终位置:{total_height}px")    
def amazon_capture_product(page, asin):
    # 定义两个时间字符串（需确保格式一致）
    dt1 = datetime.now()
    
    # 初始化结果字典，确保包含必要的字段
    result = {
        'asin': asin,
        'detaillist': ['', '', '', '', ''],  # 初始化5个空字符串
        'image_url': ''
    }
    
    try:
        page.hover('#twotabsearchtextbox')
        sleep(random.uniform(0.3,1.1))
        page.click("#twotabsearchtextbox")
        sleep(random.uniform(0.3,1.1))
        page.fill("#twotabsearchtextbox", asin)
        sleep(random.uniform(1.3,3.6))
       
        page.query_selector("#twotabsearchtextbox").press("Enter",delay=random.uniform(0.3,0.6))
        for ix in range(random.randint(1,3)):
            page.mouse.wheel(0,random.randint(100,300))
            sleep(random.uniform(0.3,1.1))
            if ix==2:
                page.keyboard.press('PageDown')
                sleep(random.uniform(0.3,1.1))
        linkselector = ".a-link-normal" 
        trytimes=0
        isexception=False
        if "captcha" in page.content().lower() or "verify" in page.content().lower():
            print("检测到验证相关元素")
            isexception=True
            return result

        if "something went wrong" in page.content().lower():
            print("检测到sorry相关元素")
            isexception=True
            time.sleep(random.uniform(2, 3)*3*60)
            return result
            
        while not isexception and not page.is_visible(linkselector) and f'/dp/{asin}' not in page.url.lower():
            sleep(random.randint(1, 2)*0.5*random.random())
            print(f"等待商品{asin}链接出现,等待{trytimes}次数")
            trytimes+=1
            if trytimes>10:
                return result

        product_elements = page.query_selector_all('div[data-asin][role="listitem"]')
        url1=page.url
        # 遍历每个产品元素并提取信息
        asins=[]
        found=False
        
        for product in product_elements:
            asin2 = product.get_attribute('data-asin')
            asins.append(asin2)
    
            if asin2 == asin:
                try:
                    # 确保元素可见
                    page.evaluate("""(element) => {
                        element.scrollIntoView({ 
                            behavior: 'smooth', 
                            block: 'center'
                        });
                    }""", product)
                    sleep(random.uniform(0.5, 1))

                    # 检查元素是否可点击
                    is_clickable = page.evaluate("""(element) => {
                        const rect = element.getBoundingClientRect();
                        const centerX = rect.left + rect.width/2;
                        const centerY = rect.top + rect.height/2;
                        const elementAtPoint = document.elementFromPoint(centerX, centerY);
                        return element.contains(elementAtPoint) || element === elementAtPoint;
                    }""", product)

                    if is_clickable:
                        # 使用JavaScript模拟点击
                        clicked = page.evaluate("""(element) => {
                            element.style.zIndex = '1000';  // 确保元素在顶层
                            element.click();
                            const link = element.querySelector('a[href*="/dp/"]');
                            if (link) {
                                link.click();
                                return true;
                            }
                            return false;
                        }""", product)
                        
                        if not clicked:
                            # 如果JavaScript点击失败，尝试直接导航
                            page.goto(f"https://www.amazon.com/dp/{asin}")
                        
                        sleep(random.uniform(1, 2))
                        
                        # 验证是否成功跳转到产品页面
                        current_url = page.url
                        if f'/dp/{asin}' not in page.url.lower():
                            print(f"成功导航到产品页面: {asin}")
                            found=True
                        else:
                            print(f"导航可能未成功，当前URL: {current_url}")
                            
                except Exception as e:
                    print(f"点击产品时出错: {e}")
                    traceback.print_exc()
                    # 如果点击失败，直接使用URL导航
                    page.goto(f"https://www.amazon.com/dp/{asin}")
                
                break
            
        for ix in range(random.randint(2,4)):
            page.mouse.wheel(0,random.randint(100,300))
            list_items = page.query_selector_all('.a-list-item.a-size-base.a-color-base')
            if list_items:
                break
            sleep(random.uniform(1.3,3.1))
            if ix==3:
                page.keyboard.press('PageDown')
                sleep(random.uniform(1.3,2.1))
            
        url2=page.url 
        if not isexception and not found:
            newurl=f'https://www.amazon.com/dp/{asin}'
            page.goto(newurl)
            sleep(random.uniform(1, 2))
            if f'/dp/{asin}' not in page.url.lower():
                found=True

        list_items = page.query_selector_all('.a-list-item.a-size-base.a-color-base')
        if not list_items:
            list_items = page.query_selector_all('li.a-spacing-mini')
        
        detaillist = []
        for index, item in enumerate(list_items):
            detaillist.append(item.text_content().strip())
        
        # 确保detaillist至少有5个元素
        while len(detaillist) < 5:
            detaillist.append('')
            
        result['detaillist'] = detaillist[:5]  # 只取前5个元素
        
        # 获取主图
        img_element = page.query_selector('img#landingImage')
        if img_element:
            image_url = img_element.get_attribute('data-old-hires')
            result['image_url'] = image_url if image_url else ''
 
        dt2 = datetime.now()
        time_diff = dt2 - dt1
        print(f"总时间差（秒）：{time_diff.total_seconds()} 秒") 
 
        return result
    except Exception as e:
        print(f"发生错误: {str(e)}")
        traceback.print_exc()
        return result
         